"use client";

import React, {
  useRef,
  useCallback,
  useMemo,
  useState,
  useEffect,
} from "react";
import {
  useCanvasSize,
  useImageData,
  useMouseInteraction,
  useInertiaScroll,
  useCanvasRenderer,
  type CanvasConfig,
  type ImageData,
} from "./useScrollCanvas";
import { useIsMobile } from "@/hooks/use-mobile";
import AnimatingImage, { AnimatingImageRef } from "./components/AnimatingImage";

const ScrollCanvas: React.FC = () => {
  const isMobile = useIsMobile();
  const [selectedImage, setSelectedImage] = useState<ImageData | null>(null);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const animationFrameRef = useRef<number | null>(null);
  const animatingImageRef = useRef<AnimatingImageRef | null>(null);

  const config: CanvasConfig = useMemo(
    () => ({
      imgTotal: 24,
      rowMax: 6,
      lineMax: 4,
      imgMargin: isMobile ? 20 : 80,
    }),
    [isMobile]
  );

  const canvasSize = useCanvasSize();

  const { imageData, setImageData, imgDimensions } = useImageData(
    config,
    canvasSize
  );

  // 计算总尺寸 - 基于固定的图片尺寸
  const totalDimensions = useMemo(
    () => ({
      width:
        config.rowMax * (imgDimensions.width + config.imgMargin) -
        config.imgMargin,
      height:
        config.lineMax * (imgDimensions.height + config.imgMargin) -
        config.imgMargin,
    }),
    [config, imgDimensions]
  );
  const { requestRedraw } = useCanvasRenderer(
    canvasRef,
    imageData,
    imgDimensions,
    canvasSize
  );

  // 移动图片
  const moveImages = useCallback(
    (deltaX: number, deltaY: number) => {
      setImageData((prevData) =>
        prevData.map((imgData) => {
          let newX = imgData.x + deltaX;
          let newY = imgData.y + deltaY;

          // 水平边界处理
          if (newX > totalDimensions.width - imgDimensions.width) {
            newX -= totalDimensions.width + config.imgMargin;
          }
          if (newX < -imgDimensions.width) {
            newX += totalDimensions.width + config.imgMargin;
          }

          // 垂直边界处理
          if (newY > totalDimensions.height - imgDimensions.height) {
            newY -= totalDimensions.height + config.imgMargin;
          }
          if (newY < -imgDimensions.height) {
            newY += totalDimensions.height + config.imgMargin;
          }

          return { ...imgData, x: newX, y: newY };
        })
      );
      requestRedraw();
    },
    [
      totalDimensions,
      imgDimensions,
      config.imgMargin,
      setImageData,
      requestRedraw,
    ]
  );

  const mouseInteraction = useMouseInteraction();

  // 惯性滚动功能
  const inertiaScroll = useInertiaScroll(moveImages);

  // 当图片数据加载完成后，触发重绘以开始动画
  useEffect(() => {
    if (imageData.length > 0) {
      requestRedraw();
    }
  }, [imageData.length, requestRedraw]);

  // 检查点击的图片
  const checkClickedImage = useCallback(
    (x: number, y: number) => {
      if (selectedImage) {
        // 如果已经有选中的图片，开始取消选中动画
        animatingImageRef.current!.startDeselectAnimation(selectedImage);
        return;
      }

      const clickedImage = imageData.find(
        (imgData) =>
          imgData.img &&
          imgData.isLoaded && // 只有加载完成的图片才能被点击
          x >= imgData.x &&
          x < imgData.x + imgDimensions.width &&
          y >= imgData.y &&
          y < imgData.y + imgDimensions.height
      );

      if (clickedImage) {
        animatingImageRef.current!.startSelectAnimation(clickedImage);
      }
    },
    [imageData, imgDimensions, selectedImage, animatingImageRef.current]
  );

  // 鼠标移动处理
  const handleCanvasMove = useCallback(
    (x: number, y: number) => {
      // 更新移动状态（用于判断是否真正拖拽）
      mouseInteraction.handleMove(x, y);

      if (!mouseInteraction.isDragging) return;

      // 停止当前的惯性滚动
      inertiaScroll.stopInertia();

      const deltaX = x - mouseInteraction.lastMousePos.x;
      const deltaY = y - mouseInteraction.lastMousePos.y;

      // 更新速度追踪
      inertiaScroll.updateVelocity(x, y);

      moveImages(deltaX, deltaY);
      mouseInteraction.setLastMousePos({ x, y });
    },
    [
      mouseInteraction.isDragging,
      mouseInteraction.lastMousePos,
      mouseInteraction.handleMove,
      moveImages,
      mouseInteraction.setLastMousePos,
      inertiaScroll,
    ]
  );

  // 鼠标点击处理
  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      // 如果惯性滚动正在进行，不触发点击
      if (inertiaScroll.isInertiaActive()) {
        return;
      }

      // 如果发生了真正的拖拽，不触发点击
      if (mouseInteraction.isRealDrag()) {
        mouseInteraction.resetDragState(); // 重置拖拽状态
        return;
      }

      // 只有在没有拖拽的情况下才处理点击
      if (!mouseInteraction.isDragging) {
        const rect = canvasRef.current?.getBoundingClientRect();
        if (rect) {
          const x = e.clientX - rect.left;
          const y = e.clientY - rect.top;
          checkClickedImage(x, y);
        }
      }

      // 重置拖拽状态
      mouseInteraction.resetDragState();
    },
    [
      mouseInteraction.isDragging,
      mouseInteraction.isRealDrag,
      mouseInteraction.resetDragState,
      checkClickedImage,
      inertiaScroll,
    ]
  );

  // 鼠标滚轮处理
  const handleWheel = useCallback(
    (e: React.WheelEvent) => {
      // 停止当前的惯性滚动
      inertiaScroll.stopInertia();

      // 使用更平滑的滚轮响应
      const deltaX = -e.deltaX * 0.5; // 减小滚轮敏感度
      const deltaY = -e.deltaY * 0.5;

      moveImages(deltaX, deltaY);
    },
    [inertiaScroll, moveImages]
  );

  // 清理动画
  useEffect(() => {
    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }
    };
  }, []);

  return (
    <div className="w-full h-full">
      {/* 动画中的图片 */}
      <AnimatingImage
        ref={animatingImageRef}
        selectedImage={selectedImage}
        imgDimensions={imgDimensions}
        canvasRef={canvasRef}
        animationFrameRef={animationFrameRef}
        setImageData={setImageData}
        setSelectedImage={setSelectedImage}
        requestRedraw={requestRedraw}
      />

      <canvas
        ref={canvasRef}
        className="w-full h-full cursor-pointer"
        onMouseDown={(e) => {
          inertiaScroll.stopInertia();
          inertiaScroll.resetVelocity();
          mouseInteraction.handleMoveStart(e.clientX, e.clientY);
        }}
        onMouseUp={(e) => {
          if (mouseInteraction.isDragging) {
            inertiaScroll.startInertia();
          }
          mouseInteraction.handleMouseUp();
        }}
        onMouseLeave={(e) => {
          if (mouseInteraction.isDragging) {
            inertiaScroll.startInertia();
          }
          mouseInteraction.handleMouseLeave();
        }}
        onMouseMove={(e) => handleCanvasMove(e.clientX, e.clientY)}
        onTouchCancel={(e) => {
          if (mouseInteraction.isDragging) {
            inertiaScroll.startInertia();
          }
          mouseInteraction.handleMouseLeave();
        }}
        onTouchStart={(e) => {
          inertiaScroll.stopInertia();
          inertiaScroll.resetVelocity();
          mouseInteraction.handleMoveStart(
            e.touches[0].clientX,
            e.touches[0].clientY
          );
        }}
        onTouchEnd={(e) => {
          if (mouseInteraction.isDragging) {
            inertiaScroll.startInertia();
          }
          mouseInteraction.handleMouseUp();
        }}
        onTouchMove={(e) =>
          handleCanvasMove(e.touches[0].clientX, e.touches[0].clientY)
        }
        onClick={handleClick}
        onWheel={handleWheel}
      />
    </div>
  );
};

export default ScrollCanvas;
